The following program estimates an unrestricted VAR, creates a model object out the estimated VAR, and obtains dynamic forecasts from the VAR by solving the model object.
' estimate VAR and forecast' replicates example in Lutkepohl (1991) pp.70-73, pp.89-91' 1/7/2000 h' last checked 3/7/2007 'change path to program path%path = @runpathcd %path ' load workfileload lut1 ' estimate VARsmpl 1960:1 1978:4var1.ls 1 2 y1 y2 y3 @ c ' replicates p.72, (3.2.22) & (3.2.24)' note that the variables are ordered differentlyfreeze(out1) var1.outputshow out1 ' make model out of estimated VARvar1.makemodel(mod1) ' change sample to forecast periodsmpl 1979:1 1980:1' solve model to obtain dynamic forecastsmod1.solve ' plot actual and forecastssmpl 1975:1 1980:1for !i=1 to var1.@neqn group gtmp y{!i} y{!i}_0 freeze(gra{!i}) gtmp.line %gname = %gname + "gra" + @str(!i) + " "next ' merge all graphs into onefreeze(gfcst) {%gname}gfcst.options size(8,2)gfcst.align(1, 0.1, 0.5)gfcst.legend position(0.1,0.1)'gfcst.scale(left) +zerolinegfcst.draw( dashline,left,rgb(155,155,155) ) 0.0 show gfcst
This program computes various criteria to select the lag order of a VAR. The results from EViews do not quite match those reported in Lutkepohl (1991, Tables 4.4 and 4.5). While Table 4.4 reports the standard LR statistics, EViews reports the modified statistics as explained in the EViews 5 User's Guide. The program computes the unmodified LR statistics that exactly replicate those reported in Table 4.5 by using the log likelihood values stored in the output matrix returned from the "mname=" option in the laglen command. Note that the stored log likelihood values do not make a degrees of freedom adjustment to the residual covariance matrix and will not match those reported in the estimation output. The information criteria reported in Table 4.5 do not appear to include the constant term in the log likelihood. However, even after correcting for the constant term, we are not able to replicate the values for AIC, HQ, and SC in Table 4.5. (There appears to be a typo in Table 4.5. The HQ and SC values for lag order 0 are unlikely to be the same.)
' VAR lag order selection' replicates Lutkepohl (1991) ' Table 4.4 (p.127) and Table 4.5 (p.130)' 1/10/2000 h' last checked 3/7/2007 'change path to program path%path = @runpathcd %path ' load workfileload lut1 ' estimate VARsmpl 1960:1 1978:4var1.ls 1 2 y1 y2 y3 @ c ' lag length criteriafreeze(tab45) var1.laglen(4,vname=vlag,mname=mlag)show tab45 !pi = @acos(-1)!c = var1.@neqn*(1+log(2*!pi)) ' unmodified LR test (exactly replicate Table 4.4, p.127)' 1st column: (unmodified) LR statistic' 2nd column: p-value !m = @rows(mlag)-2matrix(!m,2) tab44!df = var1.@neqn * var1.@neqn ' degrees of freedom of testfor !r=!m to 1 step -1 tab44(!r,1) = 2*(mlag(!r+1,1) - mlag(!r,1)) tab44(!r,2) = 1 - @cchisq(tab44(!r,1),!df)nextshow tab44
The following program computes residual diagnostics from a VAR. For the residual correlogram (autocorrelation), EViews only provides the asymptotic standard error which only depends on the sample size.
' VAR residual tests' replicates Lutkepohl (1991, pp.148-158)' 1/10/2000 h' last checked 3/7/2007 'change path to program path%path = @runpathcd %path ' load workfileload lut1 ' estimate VARsmpl 1960:1 1978:4var1.ls 1 2 y1 y2 y3 @ c ' residual correlograms (Fig 4.2, p.149)freeze(fig42) var1.correl(12,graph)show fig42 ' portmanteau test (p.152)freeze(tab_p152) var1.qstats(12,name=qstat)show tab_p152 ' normality test (p.158)freeze(tab_p158) var1.jbera(factor=chol,name=jbera)show tab_p158
The sample programs bootfcst1.prg and bootfcst2.prg compute bootstrap forecast bounds. A VAR in log first differences is estimated and forecast bounds for log first differences (bootfcst1.prg) and levels (bootfcst2.prg) are computed. The bootstrap procedure is computationally intensive (time consuming) but accounts for both coefficient uncertainty and the nonlinear log transformation without assuming normality.
'bootstrap VAR forecasts (12/15/2000)'no transformation' revised on 3/7/2007 'load workfile%data = @runpath + "lut1"load %data 'set sample objectssample smpl_est 1960:1 1978:4 'estimation samplesample smpl_fcst 1979:1 1980:4 'forecast sample 'estimate VARsmpl smpl_estvar1.ls 1 2 y1 y2 y3 @ c 'get residuals to bootstrapvar1.makeresid(n=gres) res1 res2 res3 'make model out of estimated VARvar1.makemodel(mod1) 'solve model to obtain dynamic forecastssmpl smpl_fcstmod1.solve'rename forecastssmpl smpl_estfor !i=1 to var1.@neqn rename y{!i}_0 y{!i}f y{!i}f = nanext 'assign add factors for bootstrap residualsmod1.addassign(i) @all 'set monte carlo parameters!reps = 500 'bootstrap replications!hrz = smpl_fcst.@obs 'forecast horizon 'allocate storage matrix for entire forecast distributionfor !i=1 to var1.@neqn matrix(!hrz,!reps) mboot{!i}nextvector vtmp 'temporary working vector 'set random number generatorrndseed(type=mt) 1234567 'bootstrap loopfor !i=1 to !reps 'bootstrap residuals smpl @all if res1<>na gres.resample y1_a y2_a y3_a 'generate bootstrap data mod1.solve 'estimate VAR with bootstrap data smpl smpl_est var var2.ls 1 2 y1_0 y2_0 y3_0 @ c 'make model from bootstrap estimates var2.makemodel(mod2) 'solve to bootstrap forecasts smpl smpl_fcst mod2.solve 'store bootstrap forecasts for !j=1 to var2.@neqn stom(y{!j}_0_0, vtmp, smpl_fcst) colplace(mboot{!j}, vtmp, !i) next 'clean up delete mod2next 'find bootstrap percentiles for each horizonmatrix(!hrz,var1.@neqn) mupp 'upper percentilematrix(!hrz,var1.@neqn) mlow 'lower percentilerowvector rtmp 'temporary working vector for !i=1 to !hrz for !j=1 to var1.@neqn rtmp = @rowextract(mboot{!j},!i) mupp(!i,!j) = @quantile(rtmp,0.975) mlow(!i,!j) = @quantile(rtmp,0.025) nextnext 'plot actual and forecastssmpl 1975:1 1980:4for !i=1 to var1.@neqn 'convert bounds into series series y{!i}_upp vtmp = @columnextract(mupp,!i) mtos(vtmp, y{!i}_upp, smpl_fcst) series y{!i}_low vtmp = @columnextract(mlow,!i) mtos(vtmp, y{!i}_low, smpl_fcst) 'plot graph group gtmp y{!i} y{!i}f y{!i}_upp y{!i}_low freeze(gra{!i}) gtmp.line gra{!i}.setelem(1) legend(actual) gra{!i}.setelem(2) legend(forecast) gra{!i}.setelem(3) legend(bootstrap bounds) gra{!i}.setelem(4) legend() %gname = %gname + "gra" + @str(!i) + " "next ' merge all graphs into onefreeze(gfcst) {%gname}gfcst.options size(8,2)gfcst.align(1, 0.1, 0.5)gfcst.legend columns(1) -inbox position(0.1,0.1)'gfcst.scale(left) +zerolinegfcst.option linepat ' need to set linepatgfcst.draw( dashline,left,rgb(155,155,155) ) 0.0gfcst.elem(1) lcolor(blue) lpat(solid)gfcst.elem(2) lcolor(red) lpat(solid)gfcst.elem(3) lcolor(red) lpat(dash1)gfcst.elem(4) lcolor(red) lpat(dash1)gfcst.addtext(0.1,-0.2) Bootstrap Forecast Bounds show gfcst